#include <iostream>
#include <string>
#include <chrono>
#include <sw/redis++/redis++.h>
#include <unistd.h>
#include "util.hpp"

// get 和 set
void test1(sw::redis::Redis &redis)
{
    std::cout << "get 和 set 的用法" << std::endl;

    // 清空一下数据库，避免之前的数据有干扰
    redis.flushall(); 

    // 使用 set 设置 key
    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");

    // 使用 get 获取到 key 对应的 value
    auto value1 = redis.get("key1");
    // sw::redis::OptionalString 是可以隐式转换成 bool 类型的，可以直接if判定，无效元素 返回false nil
    if(value1) {
        std::cout << "value1: " << value1.value() << std::endl;
    }

    auto value2 = redis.get("key2");
    if(value2) {
        std::cout << "value2: " << value2.value() << std::endl;
    }

    auto value3 = redis.get("key3");
    if(value3) {
        std::cout << "value3: " << value3.value() << std::endl;
    }

    auto value4 = redis.get("key4");
    if(value4) {
        std::cout << "value4: " << value4.value() << std::endl;
    }
}

// exists
void test2(sw::redis::Redis &redis)
{
    std::cout << "exists 的用法" << std::endl;
    redis.flushall();

    redis.set("key", "111");

    auto ret = redis.exists("key");
    std::cout << ret << std::endl;

    ret = redis.exists("key2");
    std::cout << ret << std::endl;

    ret = redis.exists({"key", "key2", "key3"});
    std::cout << ret << std::endl;
}

// del
void test3(sw::redis::Redis &redis)
{
    std::cout << "del 的用法" << std::endl;
    redis.flushall();

    redis.set("key", "111");
    redis.set("key2", "111");

    auto ret = redis.del({"key", "key2", "key3"});
    std::cout << ret << std::endl;

    ret = redis.exists({"key", "key2", "key3"});
    std::cout << ret << std::endl;
}

// keys
void test4(sw::redis::Redis &redis)
{
    std::cout << "keys 的用法" << std::endl;
    redis.flushall();

    redis.set("key1", "111");
    redis.set("key2", "222");
    redis.set("key3", "333");
    redis.set("key4", "444");
    redis.set("key5", "555");
    redis.set("key6", "666");
    redis.set("key7", "777");
    redis.set("key8", "888");

    // keys 的第二个参数，是一个"插入迭代器". 咱们需要先准备好一个保存结果的容器.
    // 接下来再创建一个插入迭代器指向容器的位置、就可以把 keys 获取到的结果依次通过刚才的插入迭代器插入到容器的指定位置中了.
    std::vector<std::string> result;
    auto it = std::back_insert_iterator(result);
    redis.keys("*", it);
    printContainer(result);
}

// expire and ttl
void test5(sw::redis::Redis &redis)
{
    std::cout << "expire and ttl 的用法" << std::endl;
    redis.flushall();

    redis.set("key", "111");
    redis.expire("key", std::chrono::seconds(10)); 

    sleep(5);
    
    auto time = redis.ttl("key");
    std::cout << "time: " << time << std::endl;
}

void test6(sw::redis::Redis &redis)
{
    std::cout << "type 的用法" << std::endl;
    redis.flushall();

    redis.set("key", "111");
    std::string type = redis.type("key");
    std::cout << type << std::endl; 

    redis.lpush("key2", "111");
    type = redis.type("key2");
    std::cout << type << std::endl; 

    redis.hset("key3", "aaa", "111");
    type = redis.type("key3");
    std::cout << type << std::endl; 

    redis.sadd("key4", "aaa");
    type = redis.type("key4");
    std::cout << type << std::endl; 

    redis.zadd("key5", "吕布", 99);
    type = redis.type("key5");
    std::cout << type << std::endl; 
}

int main()
{
    sw::redis::Redis redis("tcp://127.0.0.1:6379");

    // test1(redis);
    // test2(redis);
    // test3(redis);
    // test4(redis);
    // test5(redis);
    test6(redis);

    return 0;
}